using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Configuration.Install;
using System.ComponentModel;
using System.Security;
using System.Security.Policy;

namespace AttachChecker
{
    /// <summary>
    /// Custom installation action to handle code access security
    /// </summary>
    [RunInstaller(true)]
    public class Installer : System.Configuration.Install.Installer
    {
        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);
            
            // Find the machine policy level
            PolicyLevel machinePolicy = null;
            
            IEnumerator policyEnumerator = SecurityManager.PolicyHierarchy();

            while (policyEnumerator.MoveNext())
            {
                PolicyLevel level = (PolicyLevel)policyEnumerator.Current;
                if (level.Label == "Machine")
                {
                    machinePolicy = level;
                    break;
                }
            }

            if (machinePolicy == null)
            {
                throw new InstallException("Machine Policy Level not found. Code Access Security could not configured.");
            }

            // Create a FullTrust permission set
            PermissionSet permissionSet = new NamedPermissionSet("FullTrust");

            // Get the installation directory
            string assemblyPath = Context.Parameters["assemblypath"];
            string installDir = assemblyPath.Substring(0, assemblyPath.LastIndexOf("\\") + 1) + "*";

            IMembershipCondition membershipCondition = new UrlMembershipCondition(installDir);

            // Create the code group
            PolicyStatement policyStatement = new PolicyStatement(permissionSet);
            CodeGroup codeGroup = new UnionCodeGroup(membershipCondition, policyStatement);
            codeGroup.Description = "VSTO Permissions for AttachChecker";
            codeGroup.Name = "AttachChecker";

            machinePolicy.RootCodeGroup.AddChild(codeGroup);

            SecurityManager.SavePolicy();
        }
    }
}
